package mysql

import (
	user "GoDance/webserver/Entity"
	myjwt "GoDance/webserver/jwt"
	"GoDance/webserver/password_up"
	Redis "GoDance/webserver/redis"
	"database/sql"
	"fmt"
	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
	"math/rand"
	"net/http"
	"strconv"
	"time"
)

var DBB *sql.DB

func InitDB() (err error) {
	//填写数据库信息
	// 用户名：密码@tcp(本机IP:端口号)/表名
	dsn := "root:root@tcp(127.0.0.1:3306)/godance?charset=utf8mb4&parseTime=True"
	//指定数据源 （到底是 mysql还是oracle数据库） 数据库信息
	//这个时候 你的数据库信息对不对其实都不会影响后面的结果 他只是判断你的dsn格式对不对
	//db.ping() 才会尝试与数据库建立连接
	DBB, err = sql.Open("mysql", dsn)
	if err != nil { //dsn格式不对的时候会报错
		fmt.Printf(" open mysql failed %v\n", err)
		return err
	}
	err = DBB.Ping()
	if err != nil { //dsn信息不对
		fmt.Printf("111 open mysql failed %v\n", err)
		return err
	}
	//设置数据库连接池 最大连接数   有没有无所谓
	DBB.SetMaxOpenConns(10)
	return
}

//插入数据
func Insertone(user user.User) (nums sql.Result, err error) {
	//1.sql语句
	sql := `insert into user values(?,?,?,?,?,?)`
	//2.密码加密
	pass, _ := password_up.EncryptPwd(user.Password)
	//3.执行
	num, err := DBB.Exec(sql, user.ID, user.Name, user.Sex, user.Phone_number, user.Email, pass)
	if err != nil {
		fmt.Println("执行出错  ", err)
		return nil, err
	}
	return num, nil
}

//查询单条记录
func SelectById(id int64) (user.User, error) {
	var user user.User
	//1.写查询的单条记录
	sql := `select * from user where ID=?`
	//2.执行   后面的参数就是？的值
	rowOBj := DBB.QueryRow(sql, id)
	//3.拿到结果  注意传地址进去哟
	//必须调用scan方法 因为 Scan方法会释放连接
	rowOBj.Scan(&user.ID, &user.Name, &user.Sex, &user.Phone_number, &user.Email, &user.Password)
	return user, nil
}

func delete(id int64) (sql.Result, error) {
	sql := `delete from user where id=?`
	num, err := DBB.Exec(sql, id)
	if err != nil {
		fmt.Printf("删除失败")
		return nil, err
	}
	return num, nil
}

//随机一个8位数 在数据库中没有
func Get_ID() int64 {
	var rand_num int64
	for {
		rand.Seed(time.Now().Unix())
		rand_num = rand.Int63n(10000000) + 10000000
		sql := `select count(*) from user where id=?`
		rowObj := DBB.QueryRow(sql, rand_num)
		var i int
		rowObj.Scan(i)
		if i == 0 {
			break
		}
	}
	return rand_num
}

func register(user user.User) {
	_, err := Insertone(user)
	if err != nil {
		fmt.Printf("插入出错 ：", err)
	}
}

func Register() func(c *gin.Context) {
	return func(c *gin.Context) {
		InitDB()
		//接收用户发送的数据
		name := c.PostForm("name")
		sex := c.PostForm("sex")
		phone := c.PostForm("phone")
		email := c.PostForm("email")
		password := c.PostForm("password")
		code := c.PostForm("code")
		num, err := Redis.Get_code(email)
		if err != nil || code != num {
			fmt.Println("获取验证码失败")
			c.JSON(http.StatusNotFound, gin.H{
				"message": "验证码失效 或者 邮箱不正确 请检查后重新输入",
			})
		} else {
			id := Get_ID()
			tt := user.User{id, name, sex, phone, email, password}
			fmt.Println(tt)
			register(tt)
			//返回给用户结果
			c.JSON(http.StatusOK, gin.H{
				"status": 200,
				"number": id,
			})
		}
	}
}

//判断账号密码是否正确 并登录
func Sign() func(c *gin.Context) {
	return func(c *gin.Context) {
		InitDB()
		ID := c.PostForm("id")
		id, err := strconv.ParseInt(ID, 10, 64)
		if err != nil {
			fmt.Printf("强制类型转换失败")
			return
		}
		password := c.PostForm("password")
		user, _ := SelectById(id)
		OK := password_up.CheckEncryptPwdMatch(password, user.Password)
		//获取id 创建token
		token := myjwt.Get_token(user.Name)
		c.JSON(http.StatusOK, gin.H{
			"token": token,
			"ok":    OK,
		})
	}
}

func Delete() func(c *gin.Context) {
	return func(c *gin.Context) {
		InitDB()
		ID := c.PostForm("id")
		id, err := strconv.ParseInt(ID, 10, 64)
		if err != nil {
			fmt.Printf("强制类型转换失败")
			c.JSON(http.StatusOK, gin.H{
				"status":  404,
				"message": "服务器出错",
			})
			return
		}
		password := c.PostForm("password")
		user, _ := SelectById(id)
		OK := password_up.CheckEncryptPwdMatch(password, user.Password)
		Redis.Delete_all(ID)
		if OK {
			delete(id)
			c.JSON(http.StatusOK, gin.H{
				"ok": OK,
			})
		} else {
			c.JSON(http.StatusOK, gin.H{
				"status":  404,
				"message": "密码 或者 账户出现问题",
			})
		}

	}
}
